vlwkaos' digital garden

React Component Library from scratch - Testing Environment

JestReact Testing Library를 이용할 것이다.

npm i -D @testing-library/react jest jest-environment-jsdom

"test": "jest --env=jsdom"package.json에 추가하자.

테스트 추가해보기

따로 설정할 필요 없이 *.test.js형태의 파일은 자동으로 테스트로 인식한다. src/components/Button.test.js를 추가해보자.

import { render, getByText } from "@testing-library/react";
import React from "react";
import Button from "components/Button";

describe("Button", () => {
  test("should display text", () => {
    const { container } = render(<Button text="We Salute You!" />);

    getByText(container, "We Salute You!");
  });
});

이 테스트는 지정된 text값이 버튼에 잘 전달 되었는지 확인한다. getByText를 이용하면 expect할 필요없이 컴포넌트에 대해 동일한 테스트를 할 수 있다.

상호작용 테스트 해보기

아까 테스트 파일에 다음을 추가해보자

import { render, getByText, fireEvent } from "@testing-library/react";

// 다른 테스트...
  test("should handle click events", () => {
    const onClickMock = jest.fn();
    const { container } = render(
      <Button text="Click me, maybe?" onClick={onClickMock} />
    );
    const component = container.firstChild;

    fireEvent.click(component); // fireEvent를 testing-library서 import한다.

    expect(onClickMock).toBeCalled();
  });

첫 테스트와 다르게 render에서 반환된 container를 바로 참조하면 제대로 테스트가 되지 않는다. 이는 테스팅 라이브러리의 renderdiv를 만든 뒤 document.body에 붙이기 때문이다.

그래서 container.firstChild로 우리가 붙인 컴포넌트를 참조해야한다. 그후 fireEvent.click(component)로 우리가 참조하는 컴포넌트의 클릭 이벤트를 발생시킨다.

테스트 결과는 실패가 떠야한다. 우리가 만든 Button은 클릭 이벤트가 없기 때문이다.

Button.jsx로 돌아가서 다음을 추가해주자

export default function Button({ text, onClick }) {
  return <Wrapper onClick={onClick}>{text}</Wrapper>;
}

npm test 테스트가 이번에는 통과할 것이다.

스타일 테스트하기

jest-emotion 플러그인에서 toHaveStyleRule matcher을 사용하면 된다.

npm i -D @emotion/jest

toHaveStyleRule을 전역으로 사용하기 위해 두가지 설정 파일을 만들어줘야한다.

src/setupTests.js

import { matchers } from "@emotion/jest";
expect.extend(matchers);

jest.config.js

module.exports = {
  testEnvironment: "jsdom", // test에 있던 설정을 파일로 옮겨왔다.
  setupFilesAfterEnv: ["./src/setupTests.js"]
};

그리고 Button.test.js에 테스트를 추가해보자

test("should make text uppercase", () => {
  const { container } = render(<Button text="We Salute You!" />);
  const component = getByText(container, "We Salute You!");

  expect(component).toHaveStyleRule("text-transform", "uppercase");
});

css text-transform의 값이 uppercase인지 확인하는 테스트이다.

[[React Component Library from scratch - Bundle and Publish]]


참조한 글

React Component Library from scratch - Testing Environment